
cmake_minimum_required(VERSION 3.29.3)

project(
    oopenlaser
    VERSION 0.0.1
    DESCRIPTION "OpenLaser Framework"
    HOMEPAGE_URL "https://gitee.com/kcja/openlaser"
    LANGUAGES CXX
)

# 设置C++标准和Qt自动处理相关选项
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "支持的构建配置" FORCE)
set(CMAKE_BUILD_TYPE Release)

# 设置第三方库路径User-Defined
# 安装路径
set(INSTALL_EXE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin)
# 依赖环境
set(THIRD_PARTY_DIR ${CMAKE_SOURCE_DIR}/third_party)
set(EIGEN_DIR ${THIRD_PARTY_DIR}/eigen)
set(OCC_DIR ${THIRD_PARTY_DIR}/occ)
set(VTK_DIR ${THIRD_PARTY_DIR}/vtk)
set(PYTHON_DIR ${THIRD_PARTY_DIR}/python310)
set(PYTHONQT_DIR ${THIRD_PARTY_DIR}/pythonqt5)

# 确保 git 可用
find_package(Git REQUIRED)
if(NOT Git_FOUND)
    message(FATAL_ERROR "Git 未找到，请先安装 Git")
endif()

# 低版本 CMake 兼容方案（CMake < 3.15）
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
    set(TERMINAL "CON")
else()
    set(TERMINAL "/dev/stdout")
endif()

function(git_repository repo_name repo_url branch_or_tag)
    set(repo_dir ${CMAKE_CURRENT_SOURCE_DIR}/${repo_name})
    # 检查目录是否已经存在
    if(EXISTS ${repo_dir})
        message(STATUS "🚩目录 ${repo_name} 已存在.")
    else()
        message(STATUS "正在拉取依赖: ${repo_name}")
        execute_process(
            COMMAND ${GIT_EXECUTABLE} clone --progress -b ${branch_or_tag} ${repo_url} ${repo_name}
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            RESULT_VARIABLE result
            OUTPUT_FILE ${TERMINAL}
            ERROR_FILE ${TERMINAL}
        )
        if(result EQUAL 0)
            message(STATUS "✅ 拉取 ${repo_name} 成功")
        else()
            message(WARNING "❌ 拉取 ${repo_name} 失败")
            if(NOT "${output}" STREQUAL "")
                message(STATUS "❌错误: ${output}")
            endif()
            message(STATUS "❌提示：如果是网络问题，请检查网络连接或尝试手动克隆仓库")
        endif()
    endif()
endfunction()
# 自动拉取第三方库
git_repository("third_party" "https://gitee.com/kcja/openlaser-3rd-party.git" "master")

# 添加全局头文件目录
include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${EIGEN_DIR}/Eigen
    ${OCC_DIR}/include
    ${PYTHON_DIR}/include
    ${PYTHONQT_DIR}/include
    ${VTK_DIR}/include/vtk-9.3
)

# 定义源.dll文件夹和目标目录（目标目录设为build的输出目录）
if(CMAKE_BUILD_TYPE STREQUAL "Release")
    set(DLL_SOURCE_DIR 
        ${OCC_DIR}/bin
        ${PYTHON_DIR}
        ${PYTHONQT_DIR}/bin
        ${VTK_DIR}/bin
    )
    # 设置安装路径，根据build的模式分为debug和release
    set(INSTALL_DIR ${INSTALL_EXE_DIR}/release) 
    # 查找第三方库文件
    file(GLOB VTK_LIBS ${VTK_DIR}/lib/*.lib)
    file(GLOB OCC_LIBS ${OCC_DIR}/lib/*.lib)
    file(GLOB PYTHON_LIBS ${PYTHON_DIR}/libs/*.lib)
    file(GLOB PYTHONQT_LIBS ${PYTHONQT_DIR}/lib/*.lib)
    # 指定可执行程序输出目录
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE 	${INSTALL_DIR})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE 	${INSTALL_DIR})

elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
    set(DLL_SOURCE_DIR 
        ${OCC_DIR}/bind
        ${PYTHON_DIR}
        ${PYTHONQT_DIR}/bind
        ${VTK_DIR}/bind
    )
    set(INSTALL_DIR ${INSTALL_EXE_DIR}/debug) 
    # 查找第三方库文件
    file(GLOB VTK_LIBS ${VTK_DIR}/libd/*.lib)
    file(GLOB OCC_LIBS ${OCC_DIR}/libd/*.lib)
    file(GLOB PYTHON_LIBS ${PYTHON_DIR}/libs/*.lib)
    file(GLOB PYTHONQT_LIBS ${PYTHONQT_DIR}/libd/*.lib)
    # 指定可执行程序输出目录
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG 	${INSTALL_DIR})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG 	${INSTALL_DIR})
    
endif()

# 合并所有第三方库
set(THIRD_PARTY_LIBS
    ${VTK_LIBS}
    ${OCC_LIBS}
    ${PYTHON_LIBS}
    ${PYTHONQT_LIBS}
)

# 检查是否找到库
foreach(LIB_TYPE VTK_LIBS OCC_LIBS PYTHON_LIBS PYTHONQT_LIBS)
    if(NOT ${LIB_TYPE})
        message(ERROR "❌错误: 未找到${LIB_TYPE}库文件，请检查路径")
    endif()
endforeach()

# 定义全局变量，供子目录使用
set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} CACHE INTERNAL "第三方库文件列表")

# 添加子目录
add_subdirectory(src)

# 创建变量收集所有目标DLL文件
set(ALL_DLL_TARGET_FILES)
# 批量获取源.dll
foreach(DIR ${DLL_SOURCE_DIR})
    file(GLOB DLL_SOURCE_FILES "${DIR}/*.dll")
    foreach(DLL_FILE ${DLL_SOURCE_FILES})
        get_filename_component(DLL_FILENAME ${DLL_FILE} NAME)
        set(DLL_TARGET_FILE ${INSTALL_DIR}/${DLL_FILENAME})
        # 添加到目标文件列表
        list(APPEND ALL_DLL_TARGET_FILES ${DLL_TARGET_FILE})
        add_custom_command(
            OUTPUT ${DLL_TARGET_FILE}
            # 跨平台推荐用CMAKE_COMMAND
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
                ${DLL_FILE}
                ${DLL_TARGET_FILE}
            DEPENDS ${DLL_FILE}
        )
    endforeach()
endforeach()


# 创建自定义目标来执行DLL复制命令
add_custom_target(copy_dlls ALL
    COMMENT "Copying all DLL files to target directory"
    DEPENDS ${ALL_DLL_TARGET_FILES}
)
